
package edu.uts.reekie.designer.execution.edit;

import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;

import org.eclipse.draw2d.Connection;
import org.eclipse.draw2d.Graphics;
import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.PolygonDecoration;
import org.eclipse.draw2d.PolylineConnection;
import org.eclipse.draw2d.RotatableDecoration;

import org.eclipse.gef.EditPolicy;
import org.eclipse.gef.commands.Command;
import org.eclipse.gef.editparts.AbstractConnectionEditPart;
import org.eclipse.gef.editpolicies.ConnectionEditPolicy;
import org.eclipse.gef.editpolicies.ConnectionEndpointEditPolicy;
import org.eclipse.gef.requests.GroupRequest;

import edu.uts.reekie.designer.edit.AbstractConnectorEditPart;
import edu.uts.reekie.designer.execution.actions.SetConnectorDecorationAction;
import edu.uts.reekie.designer.execution.figures.AsyncDecoration;
import edu.uts.reekie.designer.execution.figures.CallbackDecoration;
import edu.uts.reekie.designer.execution.figures.SyncDecoration;
import edu.uts.reekie.designer.execution.model.*;
import edu.uts.reekie.designer.execution.model.Connector.Decoration;


/**
 * Edit part for Connector model elements.
 * <p>This edit part must implement the PropertyChangeListener interface, 
 * so it can be notified of property changes in the corresponding model element.
 * </p>
 * @author Vijay Santhanam
 */
public class ConnectorEditPart extends AbstractConnectorEditPart 
	 {


/* (non-Javadoc)
 * @see org.eclipse.gef.editparts.AbstractEditPart#createEditPolicies()
 */
protected void createEditPolicies() {
	super.createEditPolicies();
	
	// Selection handle edit policy. 
	// Makes the connection show a feedback, when selected by the user.
	//installEditPolicy(EditPolicy.CONNECTION_ENDPOINTS_ROLE,new ConnectionEndpointEditPolicy());
	// Allows the removal of the connection model element
	installEditPolicy(EditPolicy.CONNECTION_ROLE, new ConnectorEditPolicy());
	
}

/* (non-Javadoc)
 * @see org.eclipse.gef.editparts.AbstractGraphicalEditPart#createFigure()

protected IFigure createFigure() {
	PolylineConnection connection = (PolylineConnection) super.createFigure();
	applyDecorations(connection, getConnectorModel());
	connection.setLineStyle(Graphics.LINE_SOLID);  // always a solid line
	
	return connection;
}

*/
 


private Connector getConnectorModel() {
	return (Connector) getModel();
}

/* (non-Javadoc)
 * @see java.beans.PropertyChangeListener#propertyChange(java.beans.PropertyChangeEvent)
*/
public void propertyChange(PropertyChangeEvent event) {
	String property = event.getPropertyName();
	boolean updateConnectorDecorations = false; 
	
	if (Connector.PROPERTY_DIRECTION.equals(property)) {
		updateConnectorDecorations = true;
	}
	if (Connector.PROPERTY_DECORATION_SOURCE.equals(property)) {
		updateConnectorDecorations = true;
			
	}
	if (Connector.PROPERTY_DECORATION_TARGET.equals(property)) {
		updateConnectorDecorations = true;
	}

	
	if (updateConnectorDecorations){
		PolylineConnection c = (PolylineConnection) getFigure();
		int dir =  getConnectorModel().getDirection();
		applyDirectionDecorations(c,dir);
	}
	
	super.propertyChange(event);
	
}
 

protected void applyDirectionDecorations(PolylineConnection c, int direction) {
	Connector conn = getConnectorModel();
	
	c.setTargetDecoration(createDecoration(conn.getTargetDecoration())); // arrow at target end pt
	if (direction==Connector.BIDIRECTIONAL_CONNECTION){
		c.setSourceDecoration(createDecoration(conn.getSourceDecoration())); // arrow at source end point
	} else {
		c.setSourceDecoration(null); // arrow at source end point
	}
}

/*
void applyDecorations(PolylineConnection c, Connector conn){
	int direction = conn.getDirection();
	c.setTargetDecoration(createDecoration(conn.getTargetDecoration())); // arrow at target end pt
	if (direction==Connector.BIDIRECTIONAL_CONNECTION){
		c.setSourceDecoration(createDecoration(conn.getSourceDecoration())); // arrow at source end point
	} else {
		c.setSourceDecoration(null); // arrow at source end point
	}
}
*/
RotatableDecoration createDecoration(Decoration d){
	switch (d){
	case Async:
		return new AsyncDecoration();
	case Sync:
		return new SyncDecoration();
	case Callback:
		return new CallbackDecoration();
	default:
			return new PolygonDecoration();
	}
	
}



}